<?php
/**
 * Created by PhpStorm.
 * User: 69548
 * Date: 2018/8/7
 * Time: 15:33
 */

namespace app\api\model;

use think\Cache;
use think\log;
use app\common\controller\Api;
use app\api\controller\Viator as V;
class Fareharbor extends Api{

    protected $responseType = '';

    //测试key
    private $api_app = 'b88bee72-2b7e-4c65-9a0e-afe3582aecbc';
    private $api_usd_user = '8a4b3635-c274-4d88-a60c-ba42d10ad714';
    private $api_cad_user = '8a4b3635-c274-4d88-a60c-ba42d10ad714';
    private $api_mxn_user = '8a4b3635-c274-4d88-a60c-ba42d10ad714';
    private $root_url = "https://demo.fareharbor.com/api/external/v1/";
    private $cache_perfix = 'fare';

    public function __construct()
    {
        // nothing to do
    }

    public function getApiAuth($type='usd')
    {
        switch ($type){
	        case 'mxn':
                $api_auth = "?api-app=".$this->api_app."&api-user=".$this->api_mxn_user;
                break;
            case 'cad':
                $api_auth = "?api-app=".$this->api_app."&api-user=".$this->api_cad_user;
                break;
            case 'usd':
                $api_auth = "?api-app=".$this->api_app."&api-user=".$this->api_usd_user;
                break;
            default:
                $api_auth = '';
                break;
        }

        return $api_auth;
    }
    //$params 包含product date sdate edate item company
    public function getFareharborData($params=[],$is_flush=false){
        if(empty($params)){//获取所有合作商
            $cache = cache($this->cache_perfix.'_companies');
            if(!empty($cache) && !$is_flush){
                return json_decode($cache,true);
            }else{
                return $this->companies();
            }
        }

        //初始化参数
        $company    = isset($params['company'])?$params['company']:"";
        $item       = isset($params['item'])?$params['item']:"";
        $date       = isset($params['date'])?$params['date']:"";
        $sdate      = isset($params['sdate'])?$params['sdate']:"";
        $edate      = isset($params['edate'])?$params['edate']:"";
        $product    = isset($params['product'])?$params['product']:"";
        //获取商品详情
        if(!empty($product) && !empty($company)){
            $cache = cache($this->cache_perfix.'_'.$company."_".$product);
            if(empty($cache) || $is_flush){
                return $this->prodetail($company,$product);
            }
            //获取日期区间商品列表
        }elseif(!empty($sdate) && !empty($edate) && !empty($item) && !empty($company)){
            $cache = cache($this->cache_perfix.'_'.$company.'_'.$item.'_'.$sdate.'_'.$edate);
            if(empty($cache) || $is_flush){
                return $this->date_range($company,$item,$sdate,$edate);
            }
            //获取某日商品列表
        }elseif(!empty($date) && !empty($item) && !empty($company)){
            $cache = cache($this->cache_perfix.'_'.$company.'_'.$item.'_'.$date);
            if(empty($cache) || $is_flush){
                return $this->date($company,$item,$date);
            }
            //获取合作商下所有项目列表
        }elseif(!empty($company)){
            $cache = cache($this->cache_perfix.'_'.$company."_items");
            if(empty($cache) || $is_flush){
                return $this->items($company);
            }
        }else{
            $cache = [];
        }
        return json_decode($cache,true);
    }
    //获取合作商列表
    public function companies()
    {
        $companies_url = 'companies/';
        $company_type = ['usd','cad','mxn'];
        $companies = [];
        foreach ($company_type as $value){
            $api_auth = $this->getApiAuth($value);
            $url = $this->root_url.$companies_url.$api_auth;
            $data = self::http($url);
            $result = json_decode($data,true);
            if(!empty($result['companies'])){
                $companies = array_merge($companies,$result['companies']);
            }
        }

        Cache::set($this->cache_perfix.'_companies',json_encode($companies));
        return $companies;
    }

    //通过合作商获取api_auth类型
    public function getApiAuthByCompanyShortName($company_name)
    {
        $companies = $this->getFareharborData();
        if(empty($companies)) return false;
        foreach ($companies as $company){
            if($company['shortname']==$company_name){
                return $this->getApiAuth($company['currency']);
            }
        }
        return '';
    }
    //获取合作商的商品列表
    public function items($company_name)
    {
        $items_url = 'companies/'.$company_name.'/items/';
        $api_auth = $this->getApiAuthByCompanyShortName($company_name);
        $url = $this->root_url.$items_url.$api_auth;
        $data = self::http($url);
        $result = json_decode($data,true);
        if(isset($result['status']) && $result['status']!=200){
            Log::record("获取fareharbor合作商{$company_name}items列表失败,返回值是".$data);
            return [];
        }else{
            $this->updItemChineseName($result['items']);
            Cache::set($this->cache_perfix.'_'.$company_name.'_items',json_encode($result['items']));
            return $result['items'];
        }
    }

    //按日期查询商品
    public function date($company_name,$item,$date)
    {
        $date_url = 'companies/'.$company_name.'/items/'.$item.'/minimal/availabilities/date/'.$date.'/';
        $api_auth = $this->getApiAuthByCompanyShortName($company_name);
        $url = $this->root_url.$date_url.$api_auth;
        $data = self::http($url);
        $result = json_decode($data,true);
        if(empty($result['availabilities'])){
            Log::record("获取fareharbor合作商{$company_name}商品列表失败,请求值是{$company_name}-{$item}-{$date}");
            return [];
        }else {
            //封装价格
            $price_data = [];
            foreach ($result['availabilities'] as $k=>$v){
                //翻译套餐名称
                //$v['customer_type_rates'] = $this->enTransChAtDateList($v['customer_type_rates']);
                $price_data[] = $this->modifyAvailabilitiesPrice($v);
            }
            $expire_time = date('Y-m-d',strtotime("+1 day",strtotime($date)));
            Cache::set($this->cache_perfix . '_' . $company_name . '_' . $item . '_' . $date, json_encode($price_data),new \DateTime($expire_time));
            return $price_data;
        }
    }
    //按日期区间查询商品
    public function date_range($company_name,$item,$sdate,$edate)
    {
        $date_range_url = 'companies/'.$company_name.'/items/'.$item.'/minimal/availabilities/date-range/'.$sdate.'/'.$edate.'/';
        $api_auth = $this->getApiAuthByCompanyShortName($company_name);
        $url = $this->root_url . $date_range_url . $api_auth;
        $data = self::http($url);
        $result = json_decode($data,true);
        if(empty($result['availabilities'])){
            Log::record("获取fareharbor合作商{$company_name}商品列表失败,请求值是{$company_name}-{$item}-{$sdate}-{$edate}");
            return [];
        }else {
            //封装价格
            $price_data = [];
            foreach ($result['availabilities'] as $k=>$v){
                //翻译套餐名称
                //$v['customer_type_rates'] = $this->enTransChAtDateList($v['customer_type_rates']);
                $price_data[] = $this->modifyAvailabilitiesPrice($v);
            }

            return $price_data;
        }
    }
    //按PK查询商品详情
    public function prodetail($company_name,$product)
    {
        $product_url = 'companies/'.$company_name.'/availabilities/'.$product.'/';
        $api_auth = $this->getApiAuthByCompanyShortName($company_name);
        $url = $this->root_url.$product_url.$api_auth;
        $data = self::http($url);
        $result = json_decode($data,true);
        if(isset($result['status']) && $result['status']!=200){
            Log::record("获取fareharbor合作商{$company_name}商品详情失败,请求值是{$company_name}-{$product},返回值是".$data);
            return [];
        }else{
            //封装价格
            $result['availability'] = $this->modifyAvailabilitiesPrice($result['availability']);
            Cache::set($this->cache_perfix.'_'.$company_name.'_'.$product,json_encode($result['availability']));
            return $result['availability'];

        }
    }

    //创建预订单前的检查
    public function bookings_validate($company_name,$product_availabilities_pk,$params)
    {
        //封装用户数据 姓名 手机号 email 乘客所选套餐
        //检查用户信息
        if(!isset($params['userinfo']) || empty($params['userinfo'])){
            return json_encode(['code'=>-1,'msg'=>'请填写用户信息']);
        }else{
            $this->checkUserInfoData($params['userinfo']);
        }
        //检查套餐信息
        if(!isset($params['customers']) || empty($params['customers'])){
            return json_encode(['code'=>-1,'msg'=>'请选择商品套餐']);
        }else{
            $this->checkCustomersData($params['customers']);
        }
        //优惠券的编码
        $voucher_number = isset($params['voucher_number'])&&!empty($params['voucher_number'])?$params['voucher_number']:'';
        $userinfo = $params['userinfo'];
        $customers = $params['customers'];
        $validate_url = 'companies/'.$company_name.'/availabilities/'.$product_availabilities_pk.'/bookings/validate/';
        $api_auth = $this->getApiAuthByCompanyShortName($company_name);
        $url = $this->root_url.$validate_url.$api_auth;

        $postdata = [
            'voucher_number'=>$voucher_number,
            'contact'=>$userinfo,
            'customers'=>$customers,
//            'note'=>'Optional booking note'
        ];

        $data = self::http($url,'POST',json_encode($postdata));
        return json_decode($data,true);
    }
    //创建预订单
    public function bookings($company_name,$product_availabilities_pk,$params)
    {
        //封装用户数据 姓名 手机号 email 乘客所选套餐
        //检查用户信息
        if(!isset($params['userinfo']) || empty($params['userinfo'])){
            return json_encode(['code'=>-1,'msg'=>'请填写用户信息']);
        }else{
            $this->checkUserInfoData($params['userinfo']);
        }
        //检查套餐信息
        if(!isset($params['customers']) || empty($params['customers'])){
            return json_encode(['code'=>-1,'msg'=>'请选择商品套餐']);
        }else{
            $this->checkCustomersData($params['customers']);
        }
        //优惠券的编码
        $voucher_number = isset($params['voucher_number'])&&!empty($params['voucher_number'])?$params['voucher_number']:'';
        $userinfo = $params['userinfo'];
        $customers = $params['customers'];

        $bookings_url = 'companies/'.$company_name.'/availabilities/'.$product_availabilities_pk.'/bookings/';
        $api_auth = $this->getApiAuthByCompanyShortName($company_name);
        $url = $this->root_url.$bookings_url.$api_auth;

        $postdata = [
            'voucher_number'=>$voucher_number,
            'contact'=>$userinfo,
            'customers'=>$customers,
//            'note'=>'Optional booking note'
        ];

        $data = self::http($url,"POST",json_encode($postdata));

        return json_decode($data,true);
    }

    //检查用户信息
    protected function checkUserInfoData($data)
    {
        if(!isset($data['name']) || empty($data['name'])){
            return json_encode(['code'=>-1,'msg'=>'请填写用户姓名']);
        }
        if(!isset($data['phone']) || empty($data['name'])){
            return json_encode(['code'=>-1,'msg'=>'请填写用户手机号']);
        }
        if(!isset($data['phone']) || empty($data['name'])){
            return json_encode(['code'=>-1,'msg'=>'请填写用户邮箱']);
        }
    }
    //检查套餐信息
    protected function checkCustomersData($data)
    {
        foreach ($data as $key => $value){
            if(!array_key_exists('customer_type_rate',$value)){
                return json_encode(['code'=>-1,'msg'=>'请选择正确的商品套餐']);
            }
        }
    }
    private static function http($url, $method = "GET", $postfields = NULL, $headers = array())
    {
        try {
            $ssl = stripos($url, 'https://') === 0 ? true : false;
            $ci = curl_init();
            /* Curl settings */
            curl_setopt($ci, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); //在HTTP请求中包含一个"User-Agent: "头的字符串。
            curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 120);
            curl_setopt($ci, CURLOPT_TIMEOUT, 120);
            curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE);
            curl_setopt($ci, CURLOPT_ENCODING, "");
            if ($ssl) {
                curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
                curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, 2); // 从证书中检查SSL加密算法是否存在
            }
            curl_setopt($ci, CURLOPT_HEADER, FALSE);

            switch ($method) {
                case 'POST':
                    curl_setopt($ci, CURLOPT_POST, TRUE);
                    if (!empty($postfields)) {
                        curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
                    }
                    break;
            }

            curl_setopt($ci, CURLOPT_URL, $url);
            curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ci, CURLINFO_HEADER_OUT, TRUE);

            $response = curl_exec($ci);
            $httpCode = curl_getinfo($ci, CURLINFO_HTTP_CODE);
            $httpInfo = curl_getinfo($ci);

            if (FALSE === $response)
                throw new \Exception(curl_error($ci), curl_errno($ci));
        } catch (\Exception $e) {
            throw $e;
        }

        curl_close($ci);
        return $response;
    }


    //修改商品的价格 由美分变为美元 list为套餐单位
    public function modifyAvailabilitiesPrice($availability){
        if(isset($availability['customer_type_rates']) && !empty($availability['customer_type_rates'])){
            $data = $availability['customer_type_rates'];
            foreach ($data as $k=>$v){
                if($v['customer_prototype']['total']>0){
                    $price = $v['customer_prototype']['total']/100;

                }else{
                    $price = 0;
                }
               $availability['customer_type_rates'][$k]['customer_prototype']['total'] = $price;
            }
        }

        return $availability;
    }

    //将套餐名中英文转换 (new V())->etocTencent($string)
    public function enTransChAtDateList($customer_type_rates){
        $config = [
            'Adult'=>'成人',
        ];
        if(!empty($customer_type_rates)){
            foreach ($customer_type_rates as $key=>$value){
                $string = $value['customer_prototype']['display_name'];
                if(array_key_exists($string,$config)){
                    $chinese_name = $config[$string];
                }else{
                    $chinese_name = (new V())->etocTencent($string);
                }
                $customer_type_rates[$key]['customer_prototype']['chinese_name'] = $chinese_name;
            }
        }

        return $customer_type_rates;
    }

    //将套餐名中英文转换 (new V())->etocTencent($string)
    public function enTransChAtItemList($customer_prototypes){
        $config = [
            'Adult'=>'成人',
        ];
        if(!empty($customer_prototypes)){
            foreach ($customer_prototypes as $key=>$value){
                $string = $value['display_name'];
                if(array_key_exists($string,$config)){
                    $chinese_name = $config[$string];
                }else{
                    $chinese_name = (new V())->etocTencent($string);
                }
                $customer_prototypes[$key]['chinese_name'] = $chinese_name;
            }
        }

        return $customer_prototypes;
    }

    public function updItemChineseName($items)
    {
        $specnames = db('faregoods_specname')->select();
        $itemNameList = [];
        if(!empty($items)){
            foreach ($items as $key=>$value){
                if(!empty($value['customer_prototypes'])){
                    foreach ($value['customer_prototypes'] as $k=>$v){
                        $itemNameList[] = [
                            'item_id'=>$value['pk'],
                            'en_name'=>$v['display_name']
                        ];
                    }
                }
            }
        }

        $add_data = [];
        if(!empty($itemNameList)){
            if(!empty($specnames)){
                foreach ($itemNameList as $key=>$value){
                    $is_new = 1;
                    foreach ($specnames as $kk=>$vv){
                        if($vv['item_id']==$value['item_id'] && $vv['en_name']==$value['en_name']){
                            $is_new = 0;
                            break;
                        }
                    }
                    if($is_new){
                        $add_data[] = [
                            'item_id'=>$value['item_id'],
                            'en_name'=>$value['en_name'],
                            'ch_name'=>$this->enTransChSpecName($value['en_name']),
                            'update_at'=>time()
                        ];
                    }
                }
            }else{
                foreach ($itemNameList as $key=>$value){
                    $add_data[] = [
                        'item_id'=>$value['item_id'],
                        'en_name'=>$value['en_name'],
                            'ch_name'=>$this->enTransChSpecName($value['en_name']),
                        'update_at'=>time()
                    ];
                }
            }
        }

        if(!empty($add_data)){
            db('faregoods_specname')->insertAll($add_data);
        }
    }

    //将套餐名中英文转换 (new V())->etocTencent($string) 用于model数据转换
    public function enTransChSpecName($string){
        $config = [
            'Adult'=>'成人',
            'Child'=>'儿童',
            'Infant'=>'婴儿'
        ];

        if(array_key_exists($string,$config)){
            $chinese_name = $config[$string];
        }else{
            $chinese_name = (new V())->etocTencent($string);
        }

        return empty($chinese_name)?$string:$chinese_name;
    }

    //返回对应的供应商的货币单位
    public function getCompanyCurrency($company_name)
    {
        $companys = $this->getFareharborData();
        if(!empty($companys)){
            foreach ($companys as $value){
                if($value['shortname']==$company_name){
                    return $value['currency'];
                }
            }
        }
        return 'usd';
    }
}